#include "LogDataManager.h"
#include "Users.h"
#include "UserManager.h"
#include "Character.h"
#include "ChannelManager.h"
#include LOGIC_MGR_PATH
#include XMLDATA_MGR_PATH
#include "BSSocket.h"
#include "WSSocket.h"
#include "StringConverter.h"
#include "Missions.h"
#include "Channels.h"
#include "Message.h"
#include "GameGoodsManager.h"
#include "Towns.h"
#include "TownManager.h"
#include "ItemModels.h"
#include "ItemModelManager.h"
#include "UserGameLogsManager.h"
#include "CenterBattleManager.h"
#include "AIInterface.h"

using namespace AIScript;

//-----------------------------------------------------------------------

LogDataManager::LogDataManager()
{}
//-----------------------------------------------------------------------
LogDataManager::~LogDataManager()
{}
//-----------------------------------------------------------------------
String LogDataManager::GetUTF8String(String &str)
{
	if (StringUtil::checkStringUTF8(str))
		return str;
	return StringUtil::StringToUTF8(str);
}
//-----------------------------------------------------------------------
void LogDataManager::LoginLog(UserPtr pUser, const uint8 serverType)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || pUser.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Login;
	pLog->sub_type = en_LLT_Login;
	AppendUserLog(pLog, pUser);
	
	// 服务器类型
	pLog->data1 = serverType;
	if (!pUser->m_Socket.isNull())
	{
		WSSocketPtr socket = (WSSocketPtr)pUser->m_Socket.getResourcePtr();
		if (socket.isNull())
		{
			sChannelMgr.freeDumyLog(pLog);
			return;
		}		
		pLog->sdata1 = socket->GetIP();
	}
	String str = "用户";
	str += StringConverter::toString(pLog->src_id);
	str += "登录";
	str += (serverType == GameServerTypeBattle ? "战场服务器" : "世界服务器");
	str += ", ip是";
	str += pLog->sdata1;
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志记录
	sCGLogMgr.LoginOrLogoutGameLog(pUser, en_LLST_Login, GetUTF8String(str));
}
//-----------------------------------------------------------------------
void LogDataManager::LogoutLog(CharPtr pChr, const uint8 serverType)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || 
		pChr.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Login;
	pLog->sub_type = en_LLT_Logout;
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	AppendUserLog(pLog, pUser);
	// 服务器类型
	pLog->data1 = serverType;
	// switch (serverType)
	// {
		// case GameServerTypeBattle:
		// {
			// BSSocketPtr pSocket = pChr->getSocket();
			// if (!pSocket.isNull())
			// {
				// // 发送字节数
				// pLog->data2 = pSocket->getSendSize();
				// pLog->data3 = pSocket->getRealSendSize();
				// // 接收字节数
				// pLog->data4 = pSocket->getReadSize();
			// }
			// break;
		// }
		// case GameServerTypeWorld:
		// {
			// WSSocketPtr pSocket = pChr->getSocket();
			// if (!pSocket.isNull())
			// {
				// // 发送字节数
				// pLog->data2 = pSocket->getSendSize();
				// pLog->data3 = pSocket->getRealSendSize();
				// // 接收字节数
				// pLog->data4 = pSocket->getReadSize();
			// }
			// break;
		// }
		// default:
			// return;
	// }
	String str = "用户";
	str += StringConverter::toString(pLog->src_id);
	str += "退出";
	str += (serverType == GameServerTypeBattle ? "战场服务器" : "世界服务器");
	// str += "发送字节数 = ";
	// str += StringConverter::toString(pLog->data2);
	// str += ", 实际发送字节数 = ";
	// str += StringConverter::toString(pLog->data3);
	// str += "接收字节数 = ";
	// str += StringConverter::toString(pLog->data4);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志记录
	sCGLogMgr.LoginOrLogoutGameLog(pUser, en_LLST_Logout, GetUTF8String(str));
}
//-----------------------------------------------------------------------
void LogDataManager::AddExpLog(CharPtr pChr, const SourceType sourceType, const uint32 addExp, const uint32 fromId)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || 
		pChr.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Exp;
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	AppendUserLog(pLog, pUser);
	// 来源对象ID
	pLog->target_id = fromId;
	// 来源类型(来自哪方面)
	pLog->data1 = sourceType;
	// 增减多少
	pLog->data2 = addExp;
	// 当前多少级
	pLog->data3 = pChr->getUInt32Field("lv");
	// 当前经验多少
	pLog->data4 = pChr->getUInt32Field("exps");
	String str = "玩家 ";
	str += StringConverter::toString(pLog->src_id);
	switch (sourceType)
	{
		case en_ST_Game:
			str += " 在线上，";
			break;
		case en_ST_Item:
			str += " 通过使用模式ID为 ";
			str += StringConverter::toString(fromId);
			str += " 的物品，";
			break;
		case en_ST_Hortation:
			str += " 获得";
			switch ((HortationSourceID)fromId)
			{
				case en_HSI_Login:
					str += "登录奖励，";
					break;
				case en_HSI_Jackeroo:
					str += "新手补给包，";
					break;
				default:
					str += "未知奖励，";
					break;
			}
			break;
		case en_ST_Task:
			str += " 通过做ID为 ";
			str += StringConverter::toString(fromId);
			str += " 的任务，";
			break;
		case en_ST_Effect:
			str += " 通过完成模式ID为 ";
			str += StringConverter::toString(fromId);
			str += " 的效果，";
			break;
		case en_ST_Trade:
		case en_ST_Gateway:
		default:
			str += " 通过未知原因，";
			break;
	}
	str += "获得了 ";
	str += StringConverter::toString(addExp);
	str += " 经验";
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志记录
	sCGLogMgr.ExpsChangeLog(pUser, uint8(sourceType), int32(addExp), GetUTF8String(str));
}
//-----------------------------------------------------------------------
void LogDataManager::AboutTableLog(CharPtr pChr, const uint32 channelId, const TableLogType subType, const int32 & data1, const int32 & data2, const uint32 & data3, const uint32 & data4)
{
	ResourcePtr pChan = sChannelMgr.getByHandle(channelId);
	if(pChan.isNull() || pChr.isNull())
		return;
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Table;
	pLog->sub_type = subType;
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	pLog->dest_id = pChan->getUInt32Field("create_time");
	pLog->dest_type = pChan->getUInt32Field("timeout");
	
	// 房间号
	pLog->target_id = pChan->getUInt32Field("town_id");
	pLog->data1 = data1;
	pLog->data2 = data2;
	pLog->data3 = data3;
	pLog->data4 = data4;
	pLog->sdata1 = pChan->getStringField("player");
	pLog->sdata2 = pChan->getStringField("user_data");
	// 牌桌号
	pLog->target_type = channelId;
	String str = "玩家 ";
	str += StringConverter::toString(pLog->src_id);
	switch (subType)
	{
		case en_TLT_Enter:
			str += " 进入ID为 ";
			str += StringConverter::toString(pLog->target_id);
			str += " 的房间，分配的牌桌号为 ";
			str += StringConverter::toString(pLog->target_type);
			break;
		case en_TLT_Offline:
			str += " 在ID为 ";
			str += StringConverter::toString(pLog->target_id);
			str += " 的房间中，从ID号为 ";
			str += StringConverter::toString(pLog->target_type);
			str += " 的牌桌上中途离开";
			break;
		case en_TLT_Return:
			str += " 重新回到房间ID为 ";
			str += StringConverter::toString(pLog->target_id);
			str += " 牌桌ID为 ";
			str += StringConverter::toString(pLog->target_type);
			str += " 的游戏中";
			break;
		case en_TLT_Run:
			str += " 在ID为 ";
			str += StringConverter::toString(pLog->target_id);
			str += " 的房间中，从ID号为 ";
			str += StringConverter::toString(pLog->target_type);
			str += " 的牌桌逃跑，其将得到逃跑惩罚";
			break;
		case en_TLT_Complete:
			str += " 完成了房间ID为 ";
			str += StringConverter::toString(pLog->target_id);
			str += " 牌桌ID为 ";
			str += StringConverter::toString(pLog->target_type);
			str += " 的游戏";
			break;
		case en_TLT_Result:
			str += " 完成了房间ID为 ";
			str += StringConverter::toString(pLog->target_id);
			str += " 的牌局：" + StringConverter::toString(pLog->target_type) + "，获得 ";
			str += StringConverter::toString(pLog->data1) + " 筹码 和 ";			
			str += StringConverter::toString(pLog->data2);
			str += " 牌型，剩余 ";
			str += StringConverter::toString(pLog->data3);
			str += " 筹码！";
			break;
		default:
			break;
	}
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 追加新版日志逻辑
	sCGLogMgr.AboutTableLog(pUser, channelId, enTableLogSubType(subType), GetUTF8String(str));
}
//-----------------------------------------------------------------------
void LogDataManager::UpdateItemsInfoLog(CharPtr pChr, const SourceType & sourceType, const uint32 & selfModelId, const UpdateItemNumberType & operate, const uint32 & number, const uint32 & fromId, const uint32 & data7/*  = 0 */, const uint32 & data8/*  = 0 */, String strGatewayAddHead/*  = "" */)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || pChr.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	
	AppendUserLog(pLog, pUser);
	
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Item;
	pLog->sub_type = sourceType;
	// 物品所属玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 物品ID
	pLog->dest_id = selfModelId;
	// 来源对象ID
	pLog->target_id = fromId;

	// 来源类型（来自哪方面）
	pLog->data1 = sourceType;
	// 增减（1：增 2：减 3：删）
	pLog->data2 = operate;
	if (operate != en_UNT_Delete)
	{
		// 增减多少
		pLog->data3 = number;
		// 当前多少
		pLog->data4 = sGLMgr.GetItemNum(pChr, selfModelId);
		// 当前冻结多少
		pLog->data5 = sGLMgr.getCogealItemNum(pChr, selfModelId);
	}
	pLog->data7 = data7;
	pLog->data8 = data8;
	
	String str = strGatewayAddHead;
	str += " 物品数量更新：玩家 ";
	str += StringConverter::toString(pLog->src_id);
	switch (sourceType)
	{
		case en_ST_Item:
			str += " 通过使用模式ID为 ";
			str += StringConverter::toString(fromId);
			str += " 的物品，";
			break;
		case en_ST_Hortation:
			str += " 获得";
			switch ((HortationSourceID)fromId)
			{
				case en_HSI_Login:
					str += "登录奖励，";
					break;
				case en_HSI_Jackeroo:
					str += "新手补给包，";
					break;
				case en_HSI_Signin:
					str += "签到，";
					break;
				case en_HSI_Subsidy:
					str += "救济礼包，";
					break;
				default:
					str += "未知奖励，";
					break;
			}
			break;
		default:
			str += GetLogCause(sourceType);
			break;
	}
	if (operate == en_UNT_Delete)
	{
		str += "删除了模式ID为 ";
		str += StringConverter::toString(selfModelId);
		str += " 的物品";
	}
	else
	{
		str += (operate == en_UNT_Add ? "增加了 " : "减少了 ");
		str += StringConverter::toString(number);
		str += " 模式ID为 ";
		str += StringConverter::toString(selfModelId);
		str += " 的物品，当前数量为 ";
		str += StringConverter::toString(pLog->data4);
		str += " ，冻结 ";
		str += StringConverter::toString(pLog->data5);
	}
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	
	// 新版日志记录
	stItemsChangeLog parma;
	parma.pSrcUser = pUser;												// 用户
	parma.sub_type = uint8(sourceType);									// 子类型
	parma.change_model_id = selfModelId;								// 改变的道具模式ID
	parma.change_num = operate == en_UNT_Add ? number : number * (-1);	// 改变数量
	// parma.org_num;													// 改变前数量
	parma.end_num = sGLMgr.GetItemNum(pChr, selfModelId);				// 改变后数量
	parma.congeal_num = sGLMgr.getCogealItemNum(pChr, selfModelId);		// 冻结数量
	parma.extra_data1 = data7;											// 附加数据1
	parma.extra_data2 = data8;											// 附加数据2
	
	parma.info = GetUTF8String(str);									// 日志内容描述
	
	sCGLogMgr.ItemsChangeLogWithSystem(parma);
}

//-----------------------------------------------------------------------
void LogDataManager::UpdateItemsByGameResultLog(CharPtr pChr, const uint32 selfModelId, const UpdateItemNumberType operate, const uint32 number, const uint32 roomId, const uint32 channelId)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || 
		pChr.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;	
	if(!number)
		return;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Item;
	pLog->sub_type = en_ST_Game;
	// 物品所属玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 物品ID
	pLog->dest_id = selfModelId;
	// 来源对象ID（房间ID）
	pLog->target_id = roomId;
	// 牌桌ID
	pLog->target_type = channelId;
	// 来源类型（来自牌桌）
	pLog->data1 = en_ST_Game;
	// 增减（1：增 2：减 3：删）
	pLog->data2 = operate;
	if (operate != en_UNT_Delete)
	{
		// 增减多少
		pLog->data3 = number;
		// 当前多少
		pLog->data4 = sGLMgr.GetItemNum(pChr, selfModelId);
		// 当前冻结多少
		pLog->data5 = sGLMgr.getCogealItemNum(pChr, selfModelId);
	}
	
	String str = "玩家";
	str += StringConverter::toString(pLog->src_id);
	str += "在房间 ";
	
	String strRoomName = "";
	if(roomId)
	{
		
		TownPtr pTown = sTownMgr.getByHandle(roomId);
		if(!pTown.isNull())
		{
			str += "【";
			strRoomName = pTown->getStringField("name");
		}
	}
	
	str += strRoomName;
	str += "】中ID ";
	str += StringConverter::toString(channelId);
	str += "的牌桌游戏，";
	if (operate == en_UNT_Delete)
	{
		String strItemName = GetItemName(selfModelId);
		str += "【";
		str += strItemName;
		str += "】";
	}
	else
	{
		str += (operate == en_UNT_Add ? "增加了" : "减少了");
		str += StringConverter::toString(number);
		str += "【";
		
		String strItemName = GetItemName(selfModelId);
		str += strItemName;
		str += "】，当前数量为";
		str += StringConverter::toString(pLog->data4);
		str += " ，冻结";
		str += StringConverter::toString(pLog->data5);
	}
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

// 添加机器人游戏结果日志
void LogDataManager::UpdateRobotItemsInfoLog(CharPtr pChr, const SourceType & sourceType, const uint32 selfModelId, const UpdateItemNumberType operate, const uint32 number, const uint32 roomId, const uint32 channelId)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || pChr.isNull() || number == 0)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	
	AICreatureBaseInterface* pAiChrInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pAiChrInfe)
		return ;
	
	pLog->platform_id = pAiChrInfe->GetXMLData("ROBOT_SHOW_PID");
	pLog->user_name = pChr->getStringField("name");
	pLog->user_nick = pChr->getStringField("name");
	
	pLog->user_addr = pAiChrInfe->GetStringXMLData("ROBOT_ADDR");
	// pLog->user_id = pUser->getUInt32Field("reg_from");
	pLog->char_id = pChr->getHandle();
	pLog->flag = pChr->getUInt32Field("status");
	
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Item;
	pLog->sub_type = sourceType;
	// 物品所属玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pChr->getUInt32Field("gz_id");
	// 物品ID
	pLog->dest_id = selfModelId;
	// 来源对象ID（房间ID）
	pLog->target_id = roomId;
	// 牌桌ID
	pLog->target_type = channelId;
	// 来源类型（来自牌桌）
	pLog->data1 = sourceType;
	// 增减（1：增 2：减 3：删）
	pLog->data2 = operate;
	// 增减多少
	pLog->data3 = number;
	// 当前多少
	pLog->data4 = sGLMgr.GetItemNum(pChr, selfModelId);
	// 当前冻结多少
	pLog->data5 = sGLMgr.getCogealItemNum(pChr, selfModelId);
	// 机器人标志
	pLog->data6 = 1;
	
	String str = "机器人";
	str += StringConverter::toString(pLog->src_id);
	str += "在房间 ";
	
	String strRoomName = "";
	if(roomId)
	{
		
		TownPtr pTown = sTownMgr.getByHandle(roomId);
		if(!pTown.isNull())
		{
			str += "【";
			strRoomName = pTown->getStringField("name");
		}
	}
	
	str += strRoomName;
	str += "】中ID ";
	str += StringConverter::toString(channelId);
	str += "的牌桌游戏，";
	if (operate == en_UNT_Delete)
	{
		String strItemName = GetItemName(selfModelId);
		str += "【";
		str += strItemName;
		str += "】";
	}
	else
	{
		str += (operate == en_UNT_Add ? "增加了" : "减少了");
		str += StringConverter::toString(number);
		str += "【";
		
		String strItemName = GetItemName(selfModelId);
		str += strItemName;
		str += "】，当前数量为";
		str += StringConverter::toString(pLog->data4);
		str += " ，冻结";
		str += StringConverter::toString(pLog->data5);
	}
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}
	

//-----------------------------------------------------------------------
void LogDataManager::UpdateItemsByUserBuyLog(CharPtr pChr, const uint32 selfModelId, const uint32 number)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || 
		pChr.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Item;
	pLog->sub_type = en_ST_Gateway_Buy;
	// 物品所属玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 物品ID
	pLog->dest_id = selfModelId;
	// 来源类型（来自哪方面）
	pLog->data1 = en_ST_Gateway_Buy;
	// 增加
	pLog->data2 = en_UNT_Add;
	// 增减多少
	pLog->data3 = number;
	// 当前多少
	pLog->data4 = sGLMgr.GetItemNum(pChr, selfModelId);
	String str = "物品数量更新：玩家 ";
	str += StringConverter::toString(pLog->src_id);
	str += " 通过充值物品，增加了 ";
	str += StringConverter::toString(number);
	str += " 模式ID为 ";
	str += StringConverter::toString(selfModelId);
	str += " 的物品，当前数量为 ";
	str += StringConverter::toString(pLog->data4);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志记录
	stItemsChangeLog parma;
	parma.pSrcUser = pUser;												// 用户
	parma.sub_type = uint8(en_ST_Gateway_Buy);							// 子类型
	parma.change_model_id = selfModelId;								// 改变的道具模式ID
	parma.change_num = number;											// 改变数量
	// parma.org_num;													// 改变前数量
	parma.end_num = sGLMgr.GetItemNum(pChr, selfModelId);				// 改变后数量
	parma.congeal_num = sGLMgr.getCogealItemNum(pChr, selfModelId);		// 冻结数量
	
	sCGLogMgr.ItemsChangeLogWithSystem(parma);
}
//-----------------------------------------------------------------------
void LogDataManager::UpdateGoldsLog(CharPtr pChr, const SourceType sourceType, const UpdateItemNumberType operate, const uint32 number, const uint32 fromId)
{
	// 元宝没有删除的说法
	if (pChr.isNull() || operate == en_UNT_Delete)
		return;
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Gold;
	pLog->sub_type = sourceType;
	// 账号ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 来源对象ID
	pLog->target_id = fromId;
	// 来源类型（来自哪方面）
	pLog->data1 = sourceType;
	// 增减（1：增 2：减 3：删）
	pLog->data2 = operate;
	// 增减多少
	pLog->data3 = number;
	// 当前多少
	pLog->data4 = sGLMgr.GetGoldMoney(pChr);
	String str = "元宝数量更新: 玩家 ";
	str += StringConverter::toString(pChr->getSerial());
	str += " (即用户 ";
	str += StringConverter::toString(pLog->src_id);
	str += " )";
	switch (sourceType)
	{
		case en_ST_Hortation:
			str += "获得";
			switch ((HortationSourceID)fromId)
			{
				case en_HSI_Login:
					str += "登录奖励，";
					break;
				case en_HSI_Jackeroo:
					str += "新手补给包，";
					break;
				default:
					str += "未知奖励，";
					break;
			}
			break;
		case en_ST_Trade:
			str += "在商城消费，";
			break;
		case en_ST_Game:
		case en_ST_Item:
		case en_ST_Task:
		case en_ST_Effect:
		default:
			str += "通过未知原因，";
			break;
	}
	str += (operate == en_UNT_Add ? "增加了 " : "减少了 ");
	str += StringConverter::toString(number);
	str += " 元宝，当前数量为 ";
	str += StringConverter::toString(pLog->data4);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志记录
	stGoldsChangeLog parma;
	parma.pSrcUser = pUser;												// 用户
	parma.sub_type = uint8(sourceType);									// 子类型
	parma.change_num = operate == en_UNT_Add ? number : number * (-1);	// 改变数量
	// parma.org_num;													// 改变前数量
	parma.end_num = sGLMgr.GetGoldMoney(pChr);							// 改变后数量
	parma.info = GetUTF8String(str);									// 日志内容
	
	sCGLogMgr.UpdateGoldsFromGatewayLog(parma);
}
//-----------------------------------------------------------------------
void LogDataManager::UpdateGoldsFromGatewayLog(UserPtr pUser, const UpdateItemNumberType operate, const uint32 number)
{
	// 元宝没有删除的说法
	if (pUser.isNull() || operate == en_UNT_Delete)
		return;
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	pLog->sub_type = en_ST_Gateway;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Gold;
	// 账号ID
	pLog->src_id = pUser->getSerial();
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 来源类型（来自哪方面）
	pLog->data1 = en_ST_Gateway;
	// 增减（1：增 2：减 3：删）
	pLog->data2 = operate;
	// 增减多少
	pLog->data3 = number;
	// 当前多少
	pLog->data4 = pUser->getUInt32Field("golds");
	String str = "元宝数量更新: 用户 ";
	str += StringConverter::toString(pLog->src_id);
	str += " 通过网关操作，";
	str += (operate == en_UNT_Add ? "增加了 " : "减少了 ");
	str += StringConverter::toString(number);
	str += " 元宝，当前数量为 ";
	str += StringConverter::toString(pLog->data4);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志记录
	stGoldsChangeLog parma;
	parma.pSrcUser = pUser;												// 用户
	parma.sub_type = uint8(en_ST_Gateway);								// 子类型
	parma.change_num = operate == en_UNT_Add ? number : number * (-1);	// 改变数量
	// parma.org_num;													// 改变前数量
	parma.end_num = pUser->getUInt32Field("golds");						// 改变后数量
	parma.info = GetUTF8String(str);									// 日志内容
	
	sCGLogMgr.UpdateGoldsFromGatewayLog(parma);
}
//-----------------------------------------------------------------------
void LogDataManager::ChangeFiguralLog(CharPtr pChr, const SourceType sourceType, const uint32 figuralId, const uint32 fromId)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog || 
		pChr.isNull())
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	pLog->sub_type = sourceType;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Figural;
	// 玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 来源对象ID
	pLog->target_id = fromId;
	// 来源类型（来自哪方面）
	pLog->data1 = sourceType;
	// 人物形象ID
	pLog->data2 = figuralId;
	String str = "玩家 ";
	str += StringConverter::toString(pLog->src_id);
	str += " 的人物形象改变：";
	switch (sourceType)
	{
		case en_ST_Hortation:
			str += " 获得";
			switch ((HortationSourceID)fromId)
			{
				case en_HSI_Login:
					str += "登录奖励，";
					break;
				case en_HSI_Jackeroo:
					str += "新手补给包，";
					break;
				default:
					str += "未知奖励，";
					break;
			}
			break;
		case en_ST_Trade:
			str += " 在";
			if (fromId == en_ShopT_GoldShop)
				str += "元宝商城";
			else
				str += "兑换券商城";
			str += "消费，";
			break;
		case en_ST_Effect:
			str += " 通过完成模式ID为 ";
			str += StringConverter::toString(fromId);
			str += " 的效果，";
			break;
		case en_ST_Game:
		case en_ST_Item:
		case en_ST_Task:
		case en_ST_Gateway:
		default:
			str += "通过未知原因，";
			break;
	}
	str += "改变人物形象为 ";
	str += StringConverter::toString(figuralId);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版形象变化日志
	sCGLogMgr.ChangeFiguralLog(pUser, uint8(sourceType), figuralId, fromId, GetUTF8String(str));
}
//-----------------------------------------------------------------------
void LogDataManager::SystemTaxationLog(const uint32 townId, const uint32 channelId, const uint32 ante, const uint32 multy, const uint32 taxation)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_System;
	pLog->sub_type = en_SLT_Taxation;
	// 房间ID
	pLog->target_id = townId;
	// 牌桌ID
	pLog->data1 = channelId;
	// 房间底分（基本倍数）
	pLog->data2 = ante;
	// 抽水
	pLog->data3 = taxation;
	// 倍数
	pLog->data4 = multy;
	char buf[128];
	sprintf(buf, "在ID为 %d 的房间中，系统在ID为 %d 底分为 %d 最终倍数为 %d 的牌桌上抽水 %d。", townId, channelId, ante, multy, taxation);
	String str(buf);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
	// 新版日志
	sCGLogMgr.SystemTaxationLog(townId, channelId, ante, multy, taxation, uint8(en_SLT_Taxation), GetUTF8String(str));

}
//-----------------------------------------------------------------------
void LogDataManager::MissionsLog(CharPtr pChr, const uint32 & channelId, const uint32 & model_id, const uint8 & status, const uint8 & again, const uint32 & bount_model/*  = 0 */, const uint32 & num/*  = 0 */)
{
	if(pChr.isNull())
		return;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Mission;
	
	// 玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	
	pLog->dest_id = channelId;
	pLog->dest_type = ResourceTypeChannel;
	
	// 奖励
	pLog->data1 = bount_model;
	pLog->data3 = num;
	// 任务模式ID
	pLog->data4 = model_id;
	// 任务完成情况
	pLog->data5 = status;
	pLog->data2 = again;
	
	// 房间ID
	pLog->data1 = channelId;
	char buf[128];
	sprintf(buf, "%u在ID为 %u 的房间", pLog->src_id, pLog->data1);
	String str(buf);
	if (Mission::MissionStatusSucceed == pLog->data5)
		str += "完成了";
	else
		str += "未完成";
	str += " 模式ID为 ";
	str += StringConverter::toString(pLog->data4);
	str += " 的任务";
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}
//-----------------------------------------------------------------------
void LogDataManager::ChangePracticalityLog(const uint32 userId, const uint32 goodsId, const String &name, const uint32 number, const uint32 cost, const char *billId)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	AppendUserLog(pLog, userId);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Practicality;
	// 用户ID
	pLog->src_id = userId;
	pLog->src_type = RTT_USER;
	// 兑换实物ID
	pLog->data1 = goodsId;
	// 数量
	pLog->data2 = number;
	// 花费兑换券
	pLog->data3 = cost;
	// 订单号
	pLog->sdata1 = billId;
	// 商品名称
	pLog->sdata2 = name;
	char buf[256];
	sprintf(buf, "用户 %d 在兑换券商城花费 %d 兑换券兑换了 %d 数量ID为 %d 的实物商品，订单号是 %s。", userId, cost, number, goodsId, billId);
	String str(buf);
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}
//-----------------------------------------------------------------------
void LogDataManager::GatwayBuyResultLog(CharPtr pChr, String &goodsDesc, const uint32 cost)
{
	if (pChr.isNull())
		return;
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_GatwayBuyResult;
	
	// 玩家ID
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 支出金额
	pLog->data1 = cost;
	String str = "玩家 ";
	str += StringConverter::toString(pLog->src_id);
	str += "花费 ";
	str += StringConverter::toString(cost);
	str += " 的金钱成功购买了以下物品：";
	str += goodsDesc;
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

void LogDataManager::SMGameLog(CharPtr pChr, const SMGameData & smdata, const uint8 & result)
{
	if(pChr.isNull())
		return;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_SMGame;
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	// 游戏ID
	pLog->data1 = smdata.id;
	pLog->data2 = smdata.model_id;
	pLog->data3 = smdata.num;
	pLog->data4 = smdata.status;
	
	pLog->data5 = result;
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

void LogDataManager::SMGameLog(CharPtr pChr, 
						const uint32 & gameid, 
						const uint8 & result, 
						const uint32 & model_id,  
						const uint32 & num, 
						const uint32 & data4,
						const uint32 & data5)
{
	if(pChr.isNull())
		return;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_SMGame;
	pLog->src_id = pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	pLog->sub_type = gameid;
	// 游戏ID
	pLog->data1 = gameid;
	pLog->data2 = model_id;
	pLog->data3 = num;
	pLog->data4 = data4;
	pLog->data5 = data5;
	
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

void LogDataManager::SMGameMorraLog(const uint32 &serial1, const uint32 &serial2, const uint32 & val1, const uint32 & val2, const uint32 & ante, const uint32 & winner)
{
	if(!serial1 || !serial2)
		return;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr srcUser = sUserMgr.getByHandle(serial1);
	UserPtr targetUser = sUserMgr.getByHandle(serial2);
	if (!srcUser.isNull() && !targetUser.isNull())
	{
		pLog->target_id = srcUser->getUInt32Field("platform_id");
		pLog->target_type = srcUser->getUInt32Field("platform_id");
		pLog->sdata1 = srcUser->getStringField("nick");
		pLog->sdata2 = srcUser->getStringField("ip");
		pLog->sdata3 = srcUser->getStringField("addr");
		pLog->sdata4 = targetUser->getStringField("nick");
		pLog->sdata5 = targetUser->getStringField("ip");
		pLog->sdata6 = targetUser->getStringField("addr");
	}
	
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Morra;
	pLog->src_id= serial1;
	pLog->dest_id = serial2;
	pLog->data1= val1;
	pLog->data2= val2;
	pLog->data3= ante;
	pLog->data5= winner;
	
	char pstr[512] = "";
	sprintf(pstr, sMsg.getMessage("morra_log").c_str(), pLog->src_id, pLog->data1, pLog->dest_id, pLog->data2, pLog->data5, pLog->data3);
	pLog->info = pstr;
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	return;
}

void LogDataManager::TTLChannelLog(CharPtr pChr,
						const uint32 & channelId,	/* 战场ID */
						const uint32 & dest_type,	/* 战场类型 */
						const uint32 & data1,		/* 投放的金币 */		
						const uint32 & data2,		/* 1分金币 */
						const uint32 & data3,		/* 5分金币 */
						const uint32 & data4,		/* 珠宝 */
						const uint32 & data5,		/* 元宝 */
						const uint32 & data6,		/* 仙桃 */
						const uint32 & data7,		/* 小笼包 */
						const uint32 & data8,		/* 烤乳猪 */
						const uint32 & data9,		/* 木质宝箱 */
						const uint32 & data10,		/* 金宝箱 */
						const uint32 & data11,		/* 珍珠宝箱 */
						const uint32 & data12)		/* 使用时间 */
{
	if(pChr.isNull())
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_TTLChannel;
	pLog->src_id= pChr->getUInt32Field("userid");
	pLog->dest_id = channelId;
	pLog->dest_type = dest_type;
	
	pLog->data1= data1;
	pLog->data2= data2;
	pLog->data3= data3;
	pLog->data4= data4;
	pLog->data5= data5;
	pLog->data6= data6;
	pLog->data7= data7;
	pLog->data8= data8;
	pLog->fdata1= float(data9);
	pLog->fdata2= float(data10);
	pLog->fdata3= float(data11);
	pLog->fdata4= float(data12);
	
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

void LogDataManager::TTLChannelGoldsLog(CharPtr pChr,
						const uint32 & channelId,	/* 战场ID */
						const uint32 & dest_type,	/* 战场类型 */
						const uint32 & data1 ,		/* 投放的免费金币 */		
						const uint32 & data2 ,		/* 投放的付费金币 */
						const uint32 & data3 ,		/* 获得的红包数量 */
						const uint32 & data12 )		/* 获得的红包数量 */
{
	if(pChr.isNull())
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_TTLChannel;
	pLog->sub_type = en_ST_Game;
	pLog->src_id= pChr->getUInt32Field("userid");
	pLog->dest_id = channelId;
	pLog->dest_type = dest_type;
	
	pLog->data1= data1;
	pLog->data2= data2;
	pLog->data3= data3;
	
	pLog->fdata4= float(data12);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

void LogDataManager::ErrorProtocolsLog(CharPtr pChr,const uint32 & protocol_id)
{
	if(pChr.isNull())
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_ErrorProtocol;
	pLog->src_id= pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	pLog->data1= protocol_id;
	
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

// 组局日志
void LogDataManager::CreateCenterBattleLog(const uint32 & owner_pid, 
										const uint32 & cb_id, 
										const uint32 & game_id, 
										const uint32 & gz_id, 
										const uint32 & model_id, 
										const uint32 & num,
										const uint32 & status,
										const uint32 & loop,
										const uint32 & isPlayAll,
										const uint32 & mode)
{
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u", owner_pid);
	
	UserPtr pUser;
	if(lstUser.size())
		pUser = *lstUser.begin();
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if (pLog)
	{
		AppendUserLog(pLog, pUser);
		
		pLog->status = 1;
		pLog->type = enCenterBattleLimit_Battle; 
		// 组局ID
		pLog->src_id = cb_id;
		// 分区ID
		pLog->dest_id = gz_id;
		// 游戏ID
		pLog->target_id = game_id;
		// 物品ID
		pLog->data1 = model_id;
		// 数量
		pLog->data2 = num;
		// 牌局状态（0 正常结束 1 重启结束 2 超时结束 3 创建失败）
		pLog->data3 = status;
		// 游戏局数
		pLog->data4 = loop;
		// 游戏玩法
		pLog->data5 = mode;
		// 是否全部完成
		pLog->data6 = isPlayAll;
		
		// PID
		pLog->platform_id = owner_pid;
		
		String strReson = "";
		switch(status)
		{
		case 0:
			strReson = "正常结束";
			break;
		case 1:
			strReson = "重启结束";
			break;
		case 2:
			strReson = "超时结束";
			break;
		case 4:
			strReson = "创建失败";
			break;
		case 5:
			strReson = "解散（未开局）";
			break;
		case 6:
			strReson = "创建牌桌";
			break;
		}
		
		char strDesc[256];
		sprintf(strDesc, "组局ID【%u】，游戏ID【%u】，房主PID【%u】，注册来源【%u】，分区ID【%u】，报名费【金券】 x %u，行为【%s】", 
								cb_id, game_id, pLog->platform_id, pLog->user_id, gz_id, num, strReson.c_str());
		
		String strInfo(strDesc);
		pLog->info = GetUTF8String(strInfo);
		
		pLog->create_time = sGLMgr.GetCurDateTime();
		sChannelMgr.addCenterLogDB(pLog);
		
		// 增加新版日志
		stCenterBattleLog cbl;
		cbl.pUser = pUser;
		cbl.cb_id = cb_id;
		cbl.game_id = game_id;
		cbl.gz_id = gz_id;
		cbl.model_id = model_id;
		cbl.num = num;
		cbl.status = status;
		cbl.loop = loop;
		cbl.isPlayAll = isPlayAll;
		cbl.mode = mode;
		cbl.info = strDesc;
		
		sCGLogMgr.CreateCenterBattleLog(cbl);
	}
	
	sChannelMgr.freeDumyCenterLog(pLog);
}

// 组局玩家输赢日志
void LogDataManager::CenterBattleResultLog(CharPtr pChr,
									CenterBattle cb,
									const uint32 & loop,
									const int32 & winLose,
									const uint8 & finish_status,
									bool bRoomOwner)
{
	if (pChr.isNull())
		return;
	
	uint32 user_id = pChr->getUInt32Field("userid");
	if(user_id == 0)
		return ;
	
	UserPtr pUser = sUserMgr.load(user_id);
	if(pUser.isNull())
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if (pLog)
	{
		AppendUserLog(pLog, pUser);	// 追加用户信息进日志
		
		// 填充日志信息
		pLog->status = 1;
		pLog->type = enCenterBattleLimit_Player; 
		// 组局ID
		pLog->src_id = cb.cb_id;
		// 分区ID
		pLog->dest_id = cb.gz_id;
		// 游戏ID
		pLog->target_id = cb.game_id;
		
		// 游戏局数
		pLog->data1 = loop;
		// 是否房主
		pLog->data2 = bRoomOwner;
		// 总输赢
		pLog->data3 = winLose;
		// 封顶倍数
		pLog->data4 = cb.top_times;
		
		// 是否完成所有局数
		pLog->data5 = cb.limit_loop == loop;
		// 完成状态
		pLog->data6 = finish_status;
		
		// 游戏名称
		pLog->sdata1 = sXmlDataMgr.GetGameNameByGzID(cb.gz_id);
		
		String strRoomOwner = "是";
		if(!bRoomOwner)
			strRoomOwner = "否";
		
		char strDesc[256];
		sprintf(strDesc, "玩家PID【%u】是否房主【%s】 注册来源【%u】，组局ID【%u】，游戏ID【%u】，分区ID【%u】 游戏局数【%u】 最终输赢【%d】分", 
						pLog->platform_id, strRoomOwner.c_str(), pLog->user_id, cb.cb_id, cb.game_id, cb.gz_id, loop, winLose);
		
		String strInfo(strDesc);
		pLog->info = GetUTF8String(strInfo);
		
		pLog->create_time = sGLMgr.GetCurDateTime();
		sChannelMgr.addCenterLogDB(pLog);
		
		stPlayerCBResultInfo pcb_info;
		pcb_info.pUser = pUser;
		pcb_info.cb_id = cb.cb_id;					// 组局ID
		pcb_info.game_id = cb.game_id;				// 游戏ID
		pcb_info.gz_id = cb.gz_id;					// 分区ID
		pcb_info.winlose_score = winLose;			// 输赢积分
		pcb_info.top_times = cb.top_times;			// 封顶倍数
		pcb_info.isPlayAll = cb.limit_loop == loop;	// 封顶倍数
		pcb_info.loop = loop;						// 游戏轮数
		pcb_info.finish_status = finish_status;		// 完成状态
		pcb_info.strJoinCode = cb.join_code;		// 房间验证码
		pcb_info.info = strDesc;					// 日志内容
		pcb_info.mode = cb.mode;					// 游戏玩法
		
		sCGLogMgr.CenterBattleResultLog(pcb_info);
	}
	
	sChannelMgr.freeDumyCenterLog(pLog);
}

// 游戏库存修改日志
void LogDataManager::TownKunCunChangeLog(const uint32 & town_id, const int32 & change_num, const uint32 & curr_num, const uint8 & sub_type)
{
	if(!town_id)
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (pLog)
	{
		// 填充日志信息
		pLog->status = 1;
		pLog->type = en_GLT_Item; 
		pLog->sub_type = sub_type;
		
		// 房间ID
		pLog->src_id = town_id;
		pLog->src_type = RTT_TOWN;
		
		// 库存变化
		pLog->data1 = change_num;
		// 当前库存
		pLog->data2 = curr_num;
		// 创建时间
		pLog->create_time = sGLMgr.GetCurDateTime();
		
		sChannelMgr.addLogDB(pLog);
		sChannelMgr.freeDumyLog(pLog);
	}
}

// 系统庄输赢日志
void LogDataManager::SystemBankerWinLoseLog(const uint32 & town_id, const int32 & change_num, const uint32 & curr_num, const uint8 & sub_type)
{
	if(!town_id)
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (pLog)
	{
		// 填充日志信息
		pLog->status = 1;
		pLog->type = en_GLT_Item; 
		pLog->sub_type = sub_type;
		
		// 房间ID
		pLog->src_id = town_id;
		pLog->src_type = RTT_TOWN;
		
		// 库存变化
		pLog->data1 = change_num;
		// 当前库存
		pLog->data2 = curr_num;
		// 创建时间
		pLog->create_time = sGLMgr.GetCurDateTime();
		
		sChannelMgr.addLogDB(pLog);
		sChannelMgr.freeDumyLog(pLog);
	}
	
	
}

void LogDataManager::AddGamePumpLog(CharPtr pChr,
							const uint32 & fromId, 
							const uint32 & num, 
							const uint32 & data1 /* = 0 */, 
							const uint32 & data2 /* = 0 */)
{
	if(pChr.isNull() || !num)
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	AppendUserLog(pLog, pUser);
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Pump;
	pLog->src_id= pChr->getUInt32Field("userid");
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	pLog->sub_type = fromId;
	pLog->data1	= num;
	pLog->data2 = data1;
	pLog->data3 = data2;	
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

String LogDataManager::GetLogCause(const uint32 &source)
{
	String szString  = "";
	switch (source)
	{
		case en_ST_Game:
			szString = "来自游戏结果";
			break;
		case en_ST_Item:
			szString =  ("来自物品");
			break;
		case en_ST_Hortation:
			szString = ("来自奖励");
			break;
		case en_ST_Trade:
			szString = ("来自交易");
			break;
		case en_ST_Task:
			szString = ("来自任务");
			break;
		case en_ST_Effect:
			szString = ("来自效果");
			break;
		case en_ST_Gateway:
			szString = ("来自网关");
			break;
		case en_ST_Exchange:
			szString = ("来自兑换卡");
			break;
		case en_ST_GiveBack:
			szString = ("系统返还");
			break;
		case en_ST_Gateway_Buy:
			szString = ("充值物品");
			break;
		case en_ST_SignupMatch:
			szString = ("参加比赛");
			break;
		case en_ST_Match:
			szString = ("比赛奖励");
			break;
		case en_ST_Operation:
			szString = ("对象操作");
			break;
		case en_ST_SMGame:
			szString = ("小游戏");
			break;
		case en_ST_Chat:
			szString = ("聊天");
			break;
		case en_ST_Morra:
			szString = ("猜拳游戏");
			break;
		case en_ST_Roulette:
			szString = ("轮盘赌");
			break;
		case en_ST_Bank:
			szString = ("银行");
			break;
		case en_ST_Fee:
			szString = ("服务费");
			break;
		case en_ST_PTHortation:
			szString = ("平台额外奖励");
			break;
		case en_ST_TTL:
			szString = ("推推乐相关");
			break;
		case en_ST_BuZhu:
			szString = ("游戏补给");
			break;
		case en_ST_SystemGet:
			szString = ("系统没收");
			break;
		case en_ST_CreateChar:
			szString = ("来源于注册角色");
			break;
		case en_ST_LevelUp:
			szString = ("等级成长相关");
			break;
		case en_ST_Congeal:
			szString = ("冻结");
			break;
		case en_ST_UnCongeal:
			szString = ("解除冻结");
			break;
		case en_ST_OnlineBonus:
			szString = ("在线礼包");
			break;
		case en_ST_WinCombo:
			szString = ("累计获胜");
			break;
		case en_ST_Effort:
			szString = ("来自成就");
			break;
		case en_ST_NormalExchange:
			szString = ("货币兑换");
			break;
		case en_ST_UserDefined:
			szString = ("游戏内");
			break;
		case en_ST_JuBaoPen:
			szString = ("聚宝盆");
			break;
		case en_ST_HappyFarm:
			szString = ("开心牧场");
			break;
		case en_ST_LotteryTicket:
			szString = ("彩票");
			break;
		case en_ST_AllServerMail:
			szString = ("全服邮件");
			break;
		case en_ST_HongBao:
			szString = ("红包");
			break;
		case en_ST_SystemBuZhu:
			szString = ("系统补助");
			break;
		case en_ST_HuDongDaoJu:
			szString = ("互动道具-鲜花鸡蛋");
			break;
		case en_ST_CaiJin:
			szString = ("彩金");
			break;
		case en_ST_LineFruits:
			szString = ("连线水果机");
			break;
		case en_ST_LineFruitsCaiJin:
			szString = ("连线水果机彩金");
			break;
		case en_ST_LineFruitsHongBao:
			szString = ("连线水果机红包");
			break;
		case en_ST_DailyBuZhuGoldTicket:
			szString = ("每日补助");
			break;
		case en_ST_UserGiveItem:
			szString = ("玩家赠送");
			break;
		case en_ST_QiPaiQuanInvite:
			szString = ("棋牌圈分享奖励");
			break;
		case en_ST_SystemGetBankCoins:
			szString = ("系统帮玩家自动取钱");
			break;
		case en_ST_SystemSellFarm:
			szString = ("系统帮玩家出售所有动物");
			break;
		case en_ST_ActivityWinCountBounty:
			szString = ("获胜次数奖励");
			break;
		case en_ST_CharGiveItemsFromGWToChar:
			szString = ("通过网关赠送给玩家");
			break;
		case en_ST_ReturnCenterBattleOpenCoins:
			szString = ("通过组局房费返还");
			break;
		case en_ST_CenterBattle:
			szString = ("通过组局房费扣除");
			break;
		default:
			szString = ("未知原因");
			break;
	}
	
	return GetUTF8String(szString);
}

void LogDataManager::FruitScoreUpdateLog(const uint32 & pid,const uint8 & mode,
														const uint8 & bounty_id,
														const uint8 & multy,
														const uint32 & get_score,
														const uint32 & click_count)
{
	if(!pid)
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Fruit;
	pLog->src_id= pid;
	pLog->sub_type = mode;
	pLog->data1	= bounty_id;
	pLog->data2 = multy;
	pLog->data3 = get_score;
	pLog->data4 = click_count;	
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
	
}


//-----------------------------------------------------------------------
void LogDataManager::FruitScoreUseGetLog(CharPtr pChr,const uint32 & bounty_id,const uint32 & big,const uint32 & mult,const uint32 & use_coins,int get_coins)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if (NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	AppendUserLog(pLog, pChr);
	// 填充日志信息
	pLog->status = 1;
	pLog->type = en_GLT_Fruit;
	pLog->sub_type = en_ST_FruitAllPutGet;
	
	pLog->src_id = pChr->getUInt32Field("userid");
	
	pLog->data1 = bounty_id;	//奖项
	pLog->data2 = big;			//大小
	pLog->data3 = mult;			//倍数
	pLog->data4 = use_coins;	//压钱
	pLog->data5 = get_coins;	//输赢钱
	
	String str = "输赢记录：玩家【";
	str += pChr->getCharName();
	str += "】下注了奖励ID为：";
	str += StringConverter::toString(bounty_id);
	str += " 大小为：";
	str += StringConverter::toString(big);
	str += " 倍数为： ";
	str += StringConverter::toString(mult);
	str += "奖项中 下注了【";
	str += StringConverter::toString(use_coins);
	str += "】铜钱 输赢铜钱【";
	str += StringConverter::toString(get_coins);
	str += "】。";
	
	pLog->info = GetUTF8String(str);
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

void LogDataManager::ErrorProtocolsLog(const uint32 &src_id, const uint32 &dest_id, const uint32 &error, const String & info)
{
	GameLog *pLog = sChannelMgr.newDumyLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	pLog->type = en_GLT_Error;
	pLog->src_id= src_id;
	pLog->dest_id = dest_id;
	pLog->sub_type = error;
	pLog->info = info;
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addLogDB(pLog);
	sChannelMgr.freeDumyLog(pLog);
}

bool LogDataManager::AppendUserLog(GameLog *pLog, UserPtr pUser)
{
	if (pLog == NULL || pUser.isNull())
		return false;
	
	pLog->src_id = pUser->getSerial();
	pLog->src_type = pUser->getUInt32Field("active_gz_id");
	pLog->platform_id = pUser->getUInt32Field("platform_id");
	pLog->user_name = pUser->getStringField("name");
	pLog->user_nick = pUser->getStringField("nick");
	pLog->user_ip = pUser->getStringField("ip");
	pLog->user_addr = pUser->getStringField("addr");
	pLog->user_id = pUser->getUInt32Field("reg_from");
	pLog->char_id = pUser->getUInt32Field("char_id");
	pLog->flag = pUser->getUInt32Field("status");
	return true;
}

bool LogDataManager::AppendUserLog(GameLog *pLog, const uint32 &user_id)
{
	UserPtr pUser = sUserMgr.getByHandle(user_id);
	if (pUser.isNull())
		return false;
	return AppendUserLog(pLog, pUser);
}

bool LogDataManager::AppendUserLog(GameLog *pLog, CharPtr pChr)
{
	if (pChr.isNull())
		return false;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return false;
	return AppendUserLog(pLog, pUser);
}

String LogDataManager::GetItemName(const uint32 & model_id)
{
	switch(model_id)
	{
	case 1000:
		{
			return "铜钱";
		}
	case 1002:
		{
			return "红包";
		}
	default:
		break;
	}
	
	return "";
}
